package com.lamda.zhekou.task;

import com.alibaba.fastjson.JSONObject;
import com.lamda.zhekou.ZheKouApplication;
import com.lamda.zhekou.master.event.DataCallBack;
import com.lamda.zhekou.master.session.WorkerSessionScheduler;
import com.lamda.zhekou.vo.ResultVo;
import org.apache.log4j.spi.LoggerFactory;
import org.slf4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;


import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;

/**
 * Created by MJiao on 15/10/8.
 */
public class CommandWorker extends Thread {

    public static final Logger LOGGER = org.slf4j.LoggerFactory.getLogger(CommandWorker.class);

    ArrayBlockingQueue<CommandTask> commandTasks;


    private WorkerSessionScheduler workerSessionScheduler;

    private TaskExecutorCenter taskExecutorCenter;

    public CommandWorker(ArrayBlockingQueue<CommandTask> commandTasks) {
        this.commandTasks = commandTasks;
        this.workerSessionScheduler = ZheKouApplication.getConfigurableApplicationContext().getBean(WorkerSessionScheduler.class);
        this.taskExecutorCenter = ZheKouApplication.getConfigurableApplicationContext().getBean(TaskExecutorCenter.class);
    }

    @Override
    public void run() {
        try {
            CommandTask commandTask = this.commandTasks.remove();
            ResultVo resultVo = this.retryExecuteCmd(commandTask.getRoute(), commandTask.getJsonObject());
            this.taskExecutorCenter.notifyCommandTaskFinish(commandTask,resultVo);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private ResultVo retryExecuteCmd(String route, JSONObject jsonObject) {

        ResultVo resultVo = new ResultVo();
        // 开始的倒数锁
        final CountDownLatch countDownLatch = new CountDownLatch(1);
        workerSessionScheduler.push(route, jsonObject, new DataCallBack() {
            @Override
            public void responseData(JSONObject message) {
                LOGGER.info("命令执行结果:" + message);

                boolean succ = message.containsKey("succ") && message.getBoolean("succ");
                resultVo.setSucc(succ);
                resultVo.setMsg(message.getString("msg"));

                // 每个选手到达终点时，end就减一
                countDownLatch.countDown();
            }
        });
        // 等待end变为0，即所有选手到达终点
        try {
            countDownLatch.await(60 * 3, TimeUnit.SECONDS);
        } catch (InterruptedException e) {
            e.printStackTrace();
            resultVo.setSucc(false);
            resultVo.setMsg("未知异常");
        }
        return resultVo;
    }
}
